// 定义包路径
package com.hetao.jmb2c.controller;

// 导入相关类
import com.hetao.jmb2c.common.Result;
import com.hetao.jmb2c.dto.MemberBindAccountDTO;
import com.hetao.jmb2c.dto.MemberLoginDTO;
import com.hetao.jmb2c.dto.MemberRegisterDTO;
import com.hetao.jmb2c.dto.MemberUpdatePasswordDTO;
import com.hetao.jmb2c.entity.Member;
import com.hetao.jmb2c.service.MemberService;
import com.hetao.jmb2c.vo.MemberInfoVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.Random;

// 启用日志功能
@Slf4j
// 标记为REST控制器，返回JSON格式数据
@RestController
@Tag(name="会员管理")
// 设置请求路径前缀
@RequestMapping("/member")
public class MemberController {
    // 注入会员服务
    @Resource
    private MemberService memberService;

    // 当redis中的键值对，键和值的数据类型都是String时可以改用StringRedisTemplate
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Operation(
        summary = "用户登录",
        description = "使用账号密码进行登录认证",
        parameters = {
            @Parameter(name = "memberLoginDTO", description = "登录凭证", required = true,
                      content = @Content(schema = @Schema(implementation = MemberLoginDTO.class)))
        }
    )
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "登录成功",
            content = @Content(schema = @Schema(implementation = Result.class))),
        @ApiResponse(responseCode = "401", description = "用户名或密码错误"),
        @ApiResponse(responseCode = "500", description = "系统内部错误")
    })
    @PostMapping("login")
    public Result<String> login(
        @RequestBody 
        @Parameter(description = "登录请求参数", required = true,
                  content = @Content(schema = @Schema(implementation = MemberLoginDTO.class)))
        MemberLoginDTO memberLoginDTO) {
        // 调用服务层处理登录逻辑，获取token
        String token = memberService.login(memberLoginDTO);
        // 返回成功结果，包含token
        return Result.success(token);
    }

    @Operation(
        summary = "获取用户信息",
        description = "获取当前登录用户的详细信息"
    )
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "获取成功",
            content = @Content(schema = @Schema(implementation = Result.class))),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "500", description = "系统内部错误")
    })
    @GetMapping("info")
    public Result<MemberInfoVO> info() {
        // 调用服务层获取用户信息
        MemberInfoVO member = memberService.info();
        // 返回成功结果，包含用户信息
        return Result.success(member);
    }

    @Operation(
        summary = "更新密码",
        description = "修改当前登录用户的密码",
        parameters = {
            @Parameter(name = "memberUpdatePasswordDTO", description = "密码更新信息", required = true,
                     content = @Content(schema = @Schema(implementation = MemberUpdatePasswordDTO.class)))
        }
    )
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "密码更新成功"),
        @ApiResponse(responseCode = "400", description = "参数验证失败"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "500", description = "系统内部错误")
    })
    @PutMapping("updatePassword")
    public Result<Object> updatePassword(
        @RequestBody 
        @Parameter(description = "密码更新请求参数", required = true,
                 content = @Content(schema = @Schema(implementation = MemberUpdatePasswordDTO.class)))
        MemberUpdatePasswordDTO memberUpdatePasswordDTO) {
        // 调用服务层更新密码
        memberService.updatePassword(memberUpdatePasswordDTO);
        // 返回成功结果
        return Result.success();
    }

    @Operation(
        summary = "用户注册",
        description = "新用户注册账号，需要验证手机号和邮箱"
    )
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "注册成功",
            content = @Content(schema = @Schema(implementation = Result.class))),
        @ApiResponse(responseCode = "400", description = "参数验证失败"),
        @ApiResponse(responseCode = "409", description = "手机号或邮箱已存在"),
        @ApiResponse(responseCode = "500", description = "系统内部错误")
    })
    @PostMapping("register")
    public Result<Member> register(
        @RequestBody 
        @Parameter(description = "注册信息", required = true,
                 content = @Content(schema = @Schema(implementation = MemberRegisterDTO.class)))
        MemberRegisterDTO memberRegisterDTO){
        // 调用服务层注册
        log.info("memberRegisterDTO:{}",memberRegisterDTO);
        Member member = memberService.register(memberRegisterDTO);
        log.info("Controller:member:{}",member);
        // 返回成功结果
        return Result.success(member);
    }

    @Operation(
        summary = "发送验证码",
        description = "向用户手机或邮箱发送6位数字验证码，有效期5分钟"
    )
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "验证码发送成功"),
        @ApiResponse(responseCode = "400", description = "参数验证失败"),
        @ApiResponse(responseCode = "500", description = "系统内部错误")
    })
    @PostMapping("sendCode")
    public Result<Object> sendCode(
        @RequestBody 
        @Parameter(description = "接收验证码的手机或邮箱信息", required = true,
                 content = @Content(schema = @Schema(implementation = MemberRegisterDTO.class)))
        MemberRegisterDTO memberRegisterDTO){
        //发送验证码
        Random random = new Random();
        String code = random.nextInt(888888)+100000+"";
        //将验证码存入redis
        redisTemplate.opsForValue().set("code",code);
        log.info("验证码："+code);
        return Result.success();
    }

    @Operation(
        summary = "绑定账号",
        description = "绑定手机号、邮箱或第三方开放ID到当前账号"
    )
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "绑定成功"),
        @ApiResponse(responseCode = "400", description = "参数验证失败"),
        @ApiResponse(responseCode = "401", description = "未授权"),
        @ApiResponse(responseCode = "409", description = "账号已被绑定"),
        @ApiResponse(responseCode = "500", description = "系统内部错误")
    })
    @PutMapping("bindPhoneOrEmailOrOpenId")
    public Result<Object> bindPhoneOrEmailOrOpenId(
        @RequestBody 
        @Parameter(description = "绑定账号信息", required = true,
                 content = @Content(schema = @Schema(implementation = MemberBindAccountDTO.class)))
        MemberBindAccountDTO memberBindAccountDTO){
        log.info("memberBindAccountDTO:{}",memberBindAccountDTO);
        this.memberService.bindPhoneOrEmailOrOpenId(memberBindAccountDTO);
        return Result.success();
    }
}
